﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using Meraz.Core.Helpers;
using System.Web.UI;
using System.IO;

namespace Meraz.Core.Helpers
{
    public interface INetworkHelper
    {
        string Download(string url);
        IEnumerable<string> ExtractDomains(string link);
        string GetRedirect(string url);
        HttpStatusCode GetRedirect(string url, out string redirect);
        bool TryRedirect(string url, out string result);
    }
    public class NetworkHelper : INetworkHelper
    {

        public virtual string Download(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentNullException("Cannot Download without a url!");
            string results = null;
            using (WebClient wc = new WebClient())
            {
                wc.Proxy = null;
                try
                {
                    results = wc.DownloadString(url);
                }
                catch (WebException webEx)
                {
                    //The URI formed by combining BaseAddress and address is invalid. -or-
                    //An error occurred while downloading the resource.
                    Debug.WriteLine(string.Format("Failed to download from '{0}'", url));
                    Debug.WriteLine(webEx);
                }
                catch (NotSupportedException notEx)
                {
                    //The method has been called simultaneously on multiple threads.
                    Debug.WriteLine(string.Format("Failed to download from '{0}'", url));
                    Debug.WriteLine(notEx);
                }


            }
            return results;
        }

        public virtual bool TryRedirect(string url, out string result)
        {
            string redirect = GetRedirect(url);
            result = (string.IsNullOrWhiteSpace(redirect)) ?
                result = string.Empty : redirect;
            return !string.IsNullOrWhiteSpace(redirect);
        }

        public virtual HttpStatusCode GetRedirect(string url, out string redirect)
        {
            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentNullException("Cannot GetRedirect without a url!");
            redirect = string.Empty;
            HttpStatusCode resultsCode;
            using (MyWebClient wc = new MyWebClient())
            {
                wc.Proxy = null;
                try
                {
                    wc.DownloadString(url);
                    redirect = wc.ResponseUri.AbsoluteUri;
                    resultsCode = HttpStatusCode.OK;
                }
                catch (WebException webEx)
                {
                    //The URI formed by combining BaseAddress and address is invalid. -or-
                    //An error occurred while downloading the resource.
                    using (WebResponse response = webEx.Response)
                    {
                        try
                        {
                            HttpWebResponse httpResponse = (HttpWebResponse)response;
                            Debug.WriteLine("Error code: {0}", httpResponse.StatusCode);
                            using (Stream data = response.GetResponseStream())
                            {
                                string text = new StreamReader(data).ReadToEnd();
                                Debug.WriteLine(text);
                            }
                            resultsCode = httpResponse.StatusCode;
                        }catch{//sink
                            resultsCode = HttpStatusCode.BadRequest; //when failure is unknown
                        }
                    }
                }
                catch (NotSupportedException notEx)
                {
                    //The method has been called simultaneously on multiple threads.
                    Debug.WriteLine(string.Format("Failed to download from '{0}'", url));
                    Debug.WriteLine(notEx);
                    throw;
                }
            }
            return resultsCode;
        }

        public virtual string GetRedirect(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentNullException("Cannot GetRedirect without a url!");
            string results = null;
            using (MyWebClient wc = new MyWebClient())
            {
                wc.Proxy = null;
                try
                {
                    wc.DownloadString(url);
                    results = wc.ResponseUri.AbsoluteUri;
                }
                catch (WebException webEx)
                {
                    //The URI formed by combining BaseAddress and address is invalid. -or-
                    //An error occurred while downloading the resource.
                    using (WebResponse response = webEx.Response)
                    {
                        HttpWebResponse httpResponse = (HttpWebResponse)response;
                        Debug.WriteLine("Error code: {0}", httpResponse.StatusCode);
                        using (Stream data = response.GetResponseStream())
                        {
                            string text = new StreamReader(data).ReadToEnd();
                            Debug.WriteLine(text);
                        }
                        results = httpResponse.StatusCode.ToString();
                    }
                }
                catch (NotSupportedException notEx)
                {
                    //The method has been called simultaneously on multiple threads.
                    Debug.WriteLine(string.Format("Failed to download from '{0}'", url));
                    Debug.WriteLine(notEx);
                    throw;
                }
            }
            return results;
        }

        public IEnumerable<string> ExtractDomains(string link)
        {
            List<string> domains = new List<string>();
            string domain = null;
            Uri uri = new Uri(link);
            if (!uri.IsAbsoluteUri)
            {
                Debug.WriteLine(string.Format("ExtractDomains failed on '{0}'", link));
                return null;
            }
            string fullDomain = uri.Host;
            if (fullDomain.StartsWith("www."))
                fullDomain = fullDomain.Substring(4);
            string[] tokens = fullDomain.Split('.');
            Debug.Assert(tokens.Length > 1);
            domain = fullDomain;
            domains.Add(domain);
            for (int i = 0; i < tokens.Length; i++)
            {
                int dotIndex = domain.IndexOf('.');
                if (dotIndex > -1)
                    domain = domain.Substring(dotIndex + 1);
                if (domain.Contains('.'))
                    domains.Add(domain);
            }
            return domains;
        }

        public static string ExtractDomain(string link)
        {
            Uri uri = new Uri(link);
            if (!uri.IsAbsoluteUri)
                return null;
            string fullDomain = uri.Host;
            if (fullDomain.StartsWith("www."))
                fullDomain = fullDomain.Substring(4);
            string[] tokens = fullDomain.Split('.');
            Debug.Assert(tokens.Length > 1);
            return fullDomain;
        }
    }

}
